#ifndef PROTOCOL_H_
#define PROTOCOL_H_

#include "arduino/WProgram.h"

#define START_BYTE      0xE0
#define TERMINATOR_BYTE 0xEF
#define LIMIT_BYTE      0xE0

enum CommandType
{
	// Misc                  (0x00 - 0x0f)
	Connect              = 0x00,
	Disconnect           = 0x01,
	Wake                 = 0x02,
	Sleep                = 0x03,
	FeedWatchdog         = 0x04,
	EStop                = 0x05,
	RequestResendMessage = 0x06,
	// Low Level             (0x10 - 0x1f)
	ConfigPins           = 0x10,
	OutDig               = 0x11,
	OutAnl               = 0x12,
	InDigRequest         = 0x13,
	InDigStream          = 0x14,
	InAnlRequest         = 0x15,
	InAnlStream          = 0x16,
	// High Level            (0x20 - 0xdf)
	// Reserved for Protocol (0xe0 - 0xef)
	// Reserved for Internal (0xf0 - 0xff)
	Invalid              = 0xff,
};

enum MessageType
{
	Response             = 0x00,
	WatchdogFeed         = 0x01,
	AnalogInput          = 0x02,
	DigitalInput         = 0x03,
	Notification         = 0x04,
	RequestResendCommand = 0x05,
	// Reserved for Protocol (0xe0 - 0xef)
	// Reserved for Internal (0xf0 - 0xff)
};

enum FailCode
{
	// Misc                  (0x00 - 0x0f)
	Success                    = 0x00,
	AlreadyDone                = 0x01,
	InvalidCommand             = 0x02,
	NotConnected               = 0x03,
	IncorrectNumberOfArguments = 0x04,
	UnknownFail                = 0x0f,
	// IO                    (0x10 - 0x1f)
	PinNonexistant             = 0x10,
	PinOutNotIn                = 0x11,
	PinInNotOut                = 0x12,
	PinDigNotAnl               = 0x13,
	PinDigOutNotAnlIn          = 0x14,
	PinDigInNotAnlOut          = 0x15,
	PinAnlNotDig               = 0x16,
	PinAnlOutNotDigIn          = 0x17,
	PinAnlInNotDigOut          = 0x18,
	// Input Streaming       (0x20 - 0x2f)
	InvalidStreamMode          = 0x20,
	// Reserved for Protocol (0xe0 - 0xef)
	// Reserved for Internal (0xf0 - 0xff)
};

enum InputStreamMode
{
	Never    = 0x00,
	OnChange = 0x01,
	Always   = 0x02,
	// Reserved for Protocol (0xe0 - 0xef)
	// Reserved for Internal (0xf0 - 0xff)
};

enum NotificationCode
{
	NotificationEStop      = 0x00,
	NotificationChecksum   = 0x01,
	NotificationRestarting = 0x02,
	// Reserved for Protocol (0xe0 - 0xef)
	// Reserved for Internal (0xf0 - 0xff)
};

void SendMessage(uint8_t* message, int length);
void SendAnalogInput(uint8_t pin, uint8_t input);
void SendDigitalInput(uint8_t pin, uint8_t input);
void SendResponse(FailCode response, int packetID);
void SendFeedWatchdog();
void SendNotification(NotificationCode notificationCode);

void ResendMessage(int packetID);

void ReadCommand();

bool IsConnected();
void SetConnected(bool connected);

#endif /* PROTOCOL_H_ */
